package io.github.luons.mediator.core.spi.cube;

import com.google.common.base.Preconditions;
import io.github.luons.mediator.core.enums.Aggregations;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;

import java.util.Map;

@Data
public class Measure {

    /**
     * code
     */
    private String code;

    /**
     * Column
     */
    private Column column;

    private Calculator calculator = new Calculator() {
        @Override
        public double value(Map<String, Object> data) {
            return doubleValue(data, column.getAlias());
        }
    };

    public Measure() {
    }

    public Measure(String code, String columns) {
        this(code, columns, null);
    }

    public Measure(String code, String column, Calculator calculator) {
        Preconditions.checkNotNull(code, ("measure code can't be null"));
        Preconditions.checkArgument((StringUtils.isNotBlank(column)), ("measure columns should not be empty"));
        this.code = code;
        this.column = new Column(column, column, Aggregations.AVG);
        if (calculator != null) {
            this.calculator = calculator;
        }
    }

    public Measure(String code, Column column, Calculator calculator) {
        Preconditions.checkNotNull(code, ("measure code can't be null"));
        Preconditions.checkArgument((column != null), ("measure columns should not be empty"));
        this.code = code;
        this.column = column;
        if (calculator != null) {
            this.calculator = calculator;
        }
    }

    public static double doubleValue(Map<String, Object> data, String column) {
        Object obj = data.get(column);
        if (obj == null) {
            return 0.0;
        }
        if (obj instanceof Number) {
            return ((Number) obj).doubleValue();
        }
        throw new RuntimeException(String.format("invalid data type for column: %s(%s)", column, obj));
    }

    public double value(Map<String, Object> data) {
        return calculator.value(data);
    }

}
